local util = require "util"
local conf = require "conf"
local require = require
local setmetatable = setmetatable
local error = error
local table = table
local ngx = ngx
local os = os
local string = string
local tonumber = tonumber
local tostring = tostring
local math = math
package.cpath = "/usr/nginx/?.so;;"
local json = require 'cjson'
module(...)
_VERSION = '0.1'

function  create(user, args)
    local db = conf.get_mysql()
    local sql = "INSERT INTO `user` SET"

    if args.aid then
        sql = sql .. " aid = " .. args.aid .. ","
    end

    if args.org_id then
        sql = sql .. " org_id = " .. args.org_id .. ","
    end

    if args.username then
        sql = sql .. " username = '" .. args.username .. "',"
    end

    if args.pass then
        sql = sql .. " pass = '" .. args.pass .. "',"
    end

    if args.phone then
        sql = sql .. " phone = '" .. args.phone .. "',"
    end

    if args.role_id then
        sql = sql .. " role_id = " .. args.role_id .. ","
    end

    if args.name then
        sql = sql .. " name = '" .. args.name .. "',"
    end

    if args.spoint_id then
        sql = sql .. " spoint_id = '" .. args.spoint_id .. "',"
    end

    sql = sql .. " create_time = " .. os.time() .. ","
    ngx.log(ngx.ERR, sql)
    local res = db:query(sql:sub(1, -2))
    return res
end

function createController(user, args)
    local db = conf.get_mysql()
    local res = create(user, args)
    if not res or res.affected_rows < 1 then
        ngx.print(json.encode({
            err = 1,
            msg = '创建失败'
        }))
        ngx.exit(200)
    else
        local insert_id = res.insert_id
        if insert_id < 1 then
            res = db:query("SELECT LAST_INSERT_ID() AS insert_id")
            if res and res[1] and res[1].insert_id then
                insert_id = res[1].insert_id
            end
        end
        ngx.print(json.encode({
            err = 0,
            id = insert_id,
            msg = '创建成功'
        }))
        ngx.exit(200)
    end 
end

function update(user, args)
    local db = conf.get_mysql()
    local red = conf.get_redis()
    local sql = "UPDATE `user` SET "

    if args.aid then
        sql = sql .. " aid = " .. args.aid .. ","
    end

    if args.org_id then
        sql = sql .. " org_id = " .. args.org_id .. ","
    end

    if args.pass and args.pass ~= "" then
        sql = sql .. " pass = '" .. args.pass .. "',"
    end

    if args.aid then
        sql = sql .. " aid = " .. args.aid .. ","
    end

    if args.role_id then
        sql = sql .. " role_id = " .. args.role_id .. ","
    end

    if args.phone then
        sql = sql .. " phone = '" .. args.phone .. "',"
    end

    if args.name then
        sql = sql .. " name = '" .. args.name .. "',"
    end

    if args.spoint_id then
        sql = sql .. " spoint_id = '" .. args.spoint_id .. "',"
    end

    if args.username then
        sql = sql .. " username = '" .. args.username .. "',"
    end
    local where = " where"

    where = where .. " id = " .. args.id
    local ok = red:del("user"..args.id)
    local res = db:query(sql:sub(1, -2) .. where)
    return res
end

function updateController(user, args)
    if not args.id or not args.username then
        ngx.print(json.encode({
            err = 2,
            msg = '缺少id'
        }))
    end
    local res = update(user, args)
    if not res or res.affected_rows < 1 then
        ngx.print(json.encode({
            err = 1,
            msg = '更新失败'
        }))
        ngx.exit(200)
    else 
        ngx.print(json.encode({
            err = 0,
            msg = res
        }))
        ngx.exit(200)
    end
end

function delete(user, args)
    local db = conf.get_mysql()
    if not args.id or args.username then
        ngx.print(json.encode({
            err = 2,
            msg = '缺少id'
        }))
    end
    local where = " where"
    if args.id then
        where = where .. " id = " .. args.id
    else 
        where = where .. " username = " .. args.username
    end
    local res = db:query("DELETE FROM `user`" .. where)
    return res
    
end

function deleteController(user, args)
    local res = delete(user, args)
    if not res or res.affected_rows < 1 then
        ngx.print(json.encode({
            err = 1,
            msg = '更新失败'
        }))
        ngx.exit(200)
    else 
        ngx.print(json.encode({
            err = 0,
            msg = res
        }))
        ngx.exit(200)
    end
end

function search(user, args)
    local page_no, page_size, id, name, aid, role_id, phone = tonumber(args.page_no), tonumber(args.page_size), args.id, args.name, args.aid, args.role_id, args.phone
    local db = conf.get_mysql()
    local sql = "SELECT `user`.id, `user`.name, `user`.phone, `user`.spoint_id, `user`.org_id, `user`.role_id , `user`.ip_details, `user`.create_time, `user`.login_time, `user`.username,`user`.aid, `area`.name AS area FROM `user` left join `area` on `user`.aid = `area`.id WHERE 1=1 ";
    
    if name then
        sql = sql .. " AND `user`.name like '%" .. name .. "%'"
    end
    if org_id then
        local ids = conf.get_orgIds(tonumber(org_id))
        sql = sql .. " AND `user`.aid in (" ..  table.concat(ids, ",") .. ")"
    end
    if role_id then
        sql = sql .. " AND `user`.role_id = " .. tonumber(role_id)
    end

    if args.username then
        sql = sql .. " AND `user`.username like '%" .. args.username .. "%'"
    end
    
    if aid then
        local ids = conf.get_aids(tonumber(aid))
        sql = sql .. " AND `user`.aid in (" ..  table.concat(ids, ",") .. ")"
    end

    if id then
        sql = sql .. " AND `user`.id = " .. id
    end

    if phone then
        sql = sql .. " AND `user`.phone = '" .. phone .. "'"
    end

    if args.uids then
        sql = sql .. " AND `user`.id in (" .. args.uids .. ")" 
    end

    sql = sql .. " AND `user`.aid in (" ..  table.concat(user.aids, ",") .. ")"

    sql = sql .. " AND `user`.org_id in (" ..  table.concat(user.orgIds, ",") .. ")"

    local count = #(db:query(sql) or {})

    if page_no and page_size then
        sql = sql ..  " LIMIT " .. (page_no * page_size) .. "," .. page_size
    end
    local res = db:query(sql)
    return res, count
end

function searchController(user, args)
    local res, count = search(user, args)
    if not res then
        ngx.print(json.encode({
            err = 1,
            msg = '未找到相应的内容'
        }))
        ngx.exit(200)
    else
        ngx.print(json.encode({

            err = 0,
            msg = res,
            count = count
        }))
        ngx.exit(200)
    end
end

function getRole(args)
    local json = require "cjson"
    local conf = require "conf"
    local db = conf.get_mysql()
    local sql = "SELECT `user`.id, `user`.name, `user`.phone, `user`.role_id , `user`.aid, `user`.spoint_id, `role`.permissions, `role`.name AS role_name FROM `user` left join `role` on `user`.role_id = `role`.id WHERE `user`.username = '" .. args.username .. "'"
    local res = db:query(sql)
    return res
end

function getRoleController(user, args)
    local db = conf.get_mysql()
    if not args.username then
        ngx.print(json.encode({
            err = 2,
            msg = '缺少username'
        }))
        ngx.exit(200)
    end
    local res = getRole(args)
    if not res then
        ngx.print(json.encode({
            err = 1,
            msg = '未找到相应的角色'
        }))
        ngx.exit(200)
    else
        ngx.print(json.encode({
            err = 0,
            msg = res
        }))
        ngx.exit(200)
    end
end

function getVerifyCode(username, phone)
    local db = conf.get_mysql()
    local red = conf.get_redis()
    local sql = ""
    if username then
        sql = "SELECT * FROM `user` WHERE username = '" .. username .. "'"
    elseif phone then
        sql = "SELECT * FROM `user` WHERE phone = '" .. phone .. "'"
    end
    local res = db:query(sql)
    if not res or #res == 0 then
        ngx.print(json.encode({
            err = 1,
            msg = '账号不存在'
        }))
        ngx.exit(200)
    end
    if res[1].phone ~= "" then
        if tonumber(res[1].phone) ~= tonumber(phone) then
            ngx.print(json.encode({
                err = 2,
                msg = '手机号不正确'
            }))
            ngx.exit(200)
        end 
    else
        db:query("UPDATE `user` set phone = '" .. phone .. "' where username = '" .. username .."'")
    end
    local key = username and username or phone
    local res, err = red:get("vericode_"..key)
    if res ~= ngx.null then
        ngx.print(json.encode({
            err = 3,
            msg = '验证码已发送，请稍后再试'
        }))
        ngx.exit(200)
    end
    math.randomseed(tostring(os.time()):reverse():sub(1, 7))
    local veriCode = math.random(0,9) .. math.random(0,9) .. math.random(0,9) .. math.random(0,9)
    local randomNonce = os.time() .. math.random(0, 999)
    local product = "杭州迅蚁网络科技有限公司"
    local TemplateCode = "SMS_45620125"
    local signname = "捷雁云"
    local AccessKeyId = "LTAINMIADuZeDSii"
    local AccessSecret = "vdFHahdAI04f5XpGW60qeoptXkd9w3"
    local res, err1
    if username then
        res, err1 = red:set("vericode_" .. username, veriCode)
    else
        res, err1 = red:set("vericode_" .. phone, veriCode)
    end
    -- local res, err2 = red:expire("vericode_" .. phone, 60)
    if err1 or err2 then
        ngx.print(json.encode({
            err = 4,
            msg = 'redis设置失败'
        }))
        ngx.exit(200)
    else
        local sms = require 'sms'
        local params = {
            ["signname"] = signname,
            ["code"] = TemplateCode,
            ["paramstring"] = json.encode({["code"] = veriCode, ["product"] = product}),
            ["recnum"] = phone,
        }
        
        local code = sms.send(params)
        if tonumber(code) ~= 200 then
            ngx.print(json.encode{
                err = code,
                msg = "发送失败"
            })
            ngx.exit(200)
        end
        -- ngx.log(ngx.ERR, ok)
        ngx.log(ngx.ERR, code)
        ngx.log(ngx.ERR, body)
        ngx.print(json.encode({
            err = 0,
            msg = '已发送验证码，请查看手机'.. phone
        }))
        ngx.exit(200)
    end
end

-- function resetPass(username, code, newPass)
--     local db = conf.get_mysql()
--     local red = conf.get_redis()
--     local id
--     local res, err = red:get("vericode_" .. username)
--     ngx.log(ngx.ERR, res)
--     if not res or res ~= code then
--         ngx.print(json.encode({
--             err = 1,
--             msg = '验证码不对'
--         }))
--         ngx.exit(200)
--     end
--     local res = db:query("SELECT id FROM user where username = '" .. username .."'")
--     if not res then
--         ngx.print(json.encode({
--             err = 1,
--             msg = '信息有误'
--         }))
--         ngx.exit(200)
--     else 
--         id = res[1].id
--     end
--     ngx.log(ngx.ERR, id)
--     red:del(id)
--     local sql = "UPDATE `user` SET pass = '" .. newPass .. "' WHERE username = '" .. username .. "'"
--     ngx.log(ngx.ERR, sql)
--     local res = db:query(sql)
--     if not res then
--         ngx.print(json.encode({
--             err = 1,
--             msg = '信息有误'
--         }))
--         ngx.exit(200)
--     else
--         red:del("vericode_" .. username)
--         ngx.print(json.encode({
--             err = 0,
--             msg = '修改成功'
--         }))
--         ngx.exit(200)
--     end
-- end

function checkVerifyCode(key, code)
    local json = require "cjson"
    local conf = require "conf"
    local db = conf.get_mysql()
    local red = conf.get_redis()
    local res, err = red:get("vericode_" .. key)
    if res and res == code then
        red:del("vericode_" .. key)
    end
    return res
end

function verifyAdmin(username, code)
    local json = require "cjson"
    local res = checkVerifyCode(username, code)
    if not res or res ~= code then
        ngx.print(json.encode({
            err = 1,
            msg = '验证码不对'
        }))
        ngx.exit(200)
    end
    
    ngx.print(json.encode({
        err = 0,
        msg = '修改成功'
    }))
    ngx.exit(200)
end

function default(args)
    local conf = require "conf"
    if args.action == 'create' then
        local user = conf.parse_token(args, "user")
        createController(user, args)
    elseif args.action == 'update' then
        local user = conf.parse_token(args, "user")
        updateController(user, args)
    elseif args.action == 'search' then
        local user = conf.parse_token(args, "user")
        searchController(user, args)
    elseif args.action == 'delete' then
        local user = conf.parse_token(args, "user")
        deleteController(user, args)
    elseif args.action == 'getRole' then
        getRoleController(user, args)
    elseif args.action == 'resetPass' then
        resetPass(args.username, args.code, args.newPass)
    elseif args.action == 'verifyAdmin' then
        verifyAdmin(args.username, args.code)
    elseif args.action == 'getVerifyCode' then
        getVerifyCode(args.username, args.phone)
    end
end

local class_mt = {
    __newindex = function (table, key, val)
        error('attempt to write to undeclared variable "' .. key .. '"')
    end
}
setmetatable(_M, class_mt)
